package conMgr.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.text.ParseException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

import conMgr.model.Conference;
import conMgr.model.User;
import conMgr.model.UserType;
import conMgr.prog.Program;
import conMgr.ui.util.ButtonBar;
import conMgr.ui.util.SelectConferenceView;
import conMgr.ui.util.Ui;

/**
 * Main screen of Conference Manage program. 
 * This class is main frame of other panels.
 * @author Soon Bang.
 */

public class MainView extends JFrame implements Observer
{
	/**
	 * The serialization ID for this class.
	 */
	private static final long serialVersionUID = -6308327342200907203L;

	/**
	 * The default width of the frame.
	 */
	private static final int DEFAULT_WIDTH = 1280;
	  
	/**
	 * The default height of the frame.
	 */
	private static final int DEFAULT_HEIGHT = 600;
	
	/**
	 * The list of conferences panel.
	 */
	private final JPanel my_conferenceList;
	
	/**
	 * The current user.
	 */
	private User my_user;
	
	/**
	 * The button bar for this panel.
	 */
	private final ButtonBar buttonBar;
	
	/**
	 * The main frame of this program.
	 * @param the_user The current user.
	 */
	public MainView(User the_user)
	{
		super("TCSS 360B Conference Management Program");
		my_user = the_user;
		my_conferenceList = new JPanel(new GridBagLayout());
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
		
		buttonBar = new ButtonBar();
		
		Conference.getAllConferences().addObserver(this);
		
		initUi();
  
	}
	/**
	 * Initialize frame.
	 */
	private void initUi()
	{
		makeConferencePanel();
		final JScrollPane sp = new JScrollPane(my_conferenceList);
		sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		setLayout(new BorderLayout());
		
		add(sp, BorderLayout.CENTER);
		
		int col = 0;
		addGridBagInfoLabel("Hello", col++);
		addGridBagInfoLabel(my_user.getName(), col++);
		addGridBagInfoLabel("You are login as", col++);
		addGridBagInfoLabel(my_user.getType().getFriendlyName(), col++);
		makeButtonPanel();
		add(buttonBar, BorderLayout.SOUTH);

		setVisible(true);
		pack();
		setLocationRelativeTo(null);
	}

	/**
	 * Make list of conference panel which located center of main frame
	 *  depend on value of conferences.
	 * 
	 * @return my_conferenceList The list of conferences panel.
	 */
	private JPanel makeConferencePanel()
	{
		my_conferenceList.removeAll();
		my_conferenceList.repaint();
		int i=Conference.getAllConferences().size();
	    for (Conference conf : Conference.getAllConferences())
	    {
	    	final ConferenceView cv = new ConferenceView(conf, my_user);
			final GridBagConstraints constraints = new GridBagConstraints();
			constraints.gridx = 0;
			constraints.gridy = i;
			constraints.anchor = GridBagConstraints.WEST;
			constraints.insets = Ui.DEFAULT_INSETS;
	    	my_conferenceList.add(cv, constraints);
	    	conf.addObserver(this);
	    	conf.getPapers().addObserver(this);
	    	i--;
	    }
	    
	    my_conferenceList.revalidate();
	    my_conferenceList.repaint();
	    
	    return my_conferenceList;
	}	
	
	/**
	 * Make the button panel. default is 'Exit' Button. If the user type is Administrator,
	 * 'Create New Conference', 'Modify Conference' button will appear.
	 * 
	 * @return buttonPanel The button Panel.
	 */
	private void makeButtonPanel()
	{
		if(my_user.getType().equals(UserType.ADMIN))
		{
			buttonBar.addButton("Create New Conference", new CreateNewConferenceAction());
			buttonBar.addButton("Modify Conference", new ModyfyConferenceAction());
		}
		buttonBar.addButton("Logout", new LogoutAction());
		buttonBar.addButton("Exit Program", new ExitAaction());

	}
	/**
	 * The action of logout button.
	 * @author Soon Bang.
	 *
	 */
	class LogoutAction extends AbstractAction
	{
		/**
		 * The serialization ID for this class.
		 */
		private static final long serialVersionUID = 7220438750533104520L;

		/**
		 * Action of this button.
		 */
		@Override
		public void actionPerformed(ActionEvent e)
		{
			dispose();
			final LoginView lv = new LoginView();
			lv.setVisible(true);
		}
	}
	/**
	 * The action of modify conference button.
	 * @author Soon Bang.
	 *
	 */
	class ModyfyConferenceAction extends AbstractAction
	{
		/**
		 * The serialization ID for this class.
		 */
		private static final long serialVersionUID = 441771643029663126L;

		/**
		 * Action of this button.
		 */
		@Override
		public void actionPerformed(ActionEvent e)
		{
			final Conference conference = SelectConferenceView.getConference();
			if (conference != null)
			{
				try
				{
					NewConferenceView nc = null;
					try
					{
						nc = new NewConferenceView(conference);
					}
					catch (ParseException e1)
					{
						e1.printStackTrace();
					}
					nc.setVisible(true);
				}
				catch(Exception e1)
				{
					JOptionPane.showMessageDialog(null, e1.getMessage());
				}			
			}
		}
	}
	/**
	 * The action of create new conference button.
	 * @author Soon Bang.
	 *
	 */
	class CreateNewConferenceAction extends AbstractAction
	{

		/**
		 * The serialization ID for this class.
		 */
		private static final long serialVersionUID = 2741732420535494224L;

		/**
		 * The create new conference action.
		 */
		@Override
		public void actionPerformed(ActionEvent e)
		{
			try
			{
				NewConferenceView nc = null;
				try
				{
					nc = new NewConferenceView(null);
				}
				catch (ParseException e1)
				{
					e1.printStackTrace();
				}
				nc.setVisible(true);
			}
			catch(Exception e1)
			{
				JOptionPane.showMessageDialog(null, e1.getMessage());
			}
		}
	}
	/**
	 * The action of exit button.
	 * @author Soon Bang.
	 *
	 */
	class ExitAaction extends AbstractAction
	{

		/**
		 * The serialization ID for this class.
		 */
		private static final long serialVersionUID = -2547633533766346670L;

		/**
		 * The exit action.
		 */
		@Override
		public void actionPerformed(ActionEvent e)
		{
			try
			{
				Program.getDataStore().saveAll();
				dispose();
			}
			catch(Exception e1)
			{
				JOptionPane.showMessageDialog(null, e1.getMessage());
			}
		}
	}
	/**
	 * Adds a new field label to a grid bag.
	 * @param text The text to display in the label.
	 * @param row The row of the grid that the label belongs in.
	 */
	private void addGridBagInfoLabel(final String the_name, final int col)
	{
		final JLabel label = new JLabel(the_name);
		final GridBagConstraints constraints = new GridBagConstraints();
		constraints.gridx = col;
		constraints.gridy = 0;
		constraints.insets = Ui.DEFAULT_INSETS;
		constraints.anchor = GridBagConstraints.SOUTHWEST;
		buttonBar.add(label, constraints);
	}
    /**
     * Observer update.
     */
	@Override
    public void update(Observable arg0, Object arg1)
    {
		Program.getDataStore().saveAll();
		makeConferencePanel();
    }
}
